package com.hxb.api.web.servlet;


import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.hxb.util.HttpUtils;
import com.hxb.util.exception.HttpException;
import com.hxb.util.http.RequestParams;
import com.hxb.util.http.Response;
import com.hxb.util.http.ResponseStream;
import com.hxb.util.http.client.HttpRequest;

/**
 * 将浏览器过来的请求转发给目标服务器组件进行处理
 * 
 * @author MARK
 *
 */
public class RequestDispacherServlet extends HttpServlet {
  
	
	private HttpUtils httpUtils = null;
	private Gson gson = null;

	public RequestDispacherServlet() {
		super();
	}
	
	public void init() throws ServletException {
		httpUtils = new HttpUtils();
		gson = new Gson();
	}

	public void destroy() {
		super.destroy(); // Just puts "destroy" string in log
		httpUtils = null;
		gson = null; 
	}
	
	@Override
	public void service(ServletRequest arg0, ServletResponse arg1)
			throws ServletException, IOException {
		long startTime = System.currentTimeMillis();
		long endTime = 0;
		HttpServletRequest request = (HttpServletRequest)arg0;
		HttpServletResponse response = (HttpServletResponse)arg1;
		String result = null;
		try {
			result = dispachRequest(request);
		} catch (HttpException e) {
			result = gson.toJson(new Response(String.valueOf(e.getExceptionCode()), e.getMessage()));
			e.printStackTrace();
		}catch (Exception e) {
			result = gson.toJson(new Response(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), e.getMessage()));
			e.printStackTrace();
		}finally{
			endTime = System.currentTimeMillis();
			long costTime = endTime-startTime;
			result = processResult(result, costTime);
			renderJson(response,result);
		}
	}
	
	/**
	 * 将请求转发给目标服务器来处理
	 * @param request
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 */
	private String dispachRequest(HttpServletRequest request) throws HttpException, IOException {
		String url = request.getParameter("_url");
		RequestParams params = new RequestParams();
		Map<String, String[]> map = request.getParameterMap();
		for (String key : map.keySet()) {
			String[] values = map.get(key);
			for (String value : values) {
				params.addBodyParameter(key, value);
			}
		}
		HttpRequest.HttpMethod post = HttpRequest.HttpMethod.POST;
		ResponseStream rs = httpUtils.sendSync(post, url, params);
		return rs.readString();
	}
	
	/**
	 * 将目标服务器组件的响应时间添加到返回的JSON中
	 * @param result
	 * @param costTime
	 * @return
	 */
	private String processResult(String result, long costTime) {
		try {
			 //JsonElement是根节点，它可能是一个对象数组为空或者java原始类型　
			 JsonParser parser = new JsonParser();
			 JsonElement element = parser.parse(result);
			 JsonObject jsonObj = element.getAsJsonObject();
			 if (jsonObj.isJsonObject()) {
				 jsonObj.addProperty("serverCostTime", costTime);
				 result =  jsonObj.toString();
			 }
		} catch (JsonParseException e) {
			result = gson.toJson(new Response(String.valueOf(HttpServletResponse.SC_INTERNAL_SERVER_ERROR), "Json格式有误："+result));
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 向客户端输出JSON数据
	 * @param response
	 * @param str
	 */
	public static void renderJson(HttpServletResponse response,String str) {	
		response.setContentType("application/json;charset=UTF-8");   
		response.setHeader("Cache-Control","no-cache"); 
		PrintWriter out = null;	
		try {
			out = response.getWriter();
			out.write(str);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			out.close();			
		}
	}

}
